﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace MyDelegateDemo
{
    public delegate void NoReturnNoParaOutClass();
    public class CustomDelegate  // : MulticastDelegate
    {
        public CustomDelegate()
        {
        }


        public delegate void NoReturnNoPara();
        public delegate void NoReturnWithPara(int x, int y);
        public delegate int WithReturnNoPara();
        public delegate int WithReturnWithPara(out int x, ref int y);


        //一. 什么是委托?
        //1.形如一个方法,有修饰符,带有关键字:delegate, 有返回值的声明, 有参数的声明----委托了;和方法不一样, 就是没有方法体的部分;
        //2.委托的本质究竟是什么? 底层是什么, 原理是什么?---工具--IL-Spay--反编译工具
        //3.委托的本质是其实是一个Class 类, 继承自一个[System.Runtime]System.MulticastDelegate 特殊类, 委托是一个类, 就可以把委托当做一个类来使用?  
        //4. 实例化委托, 可以执行委托 Invoke方法--执行委托--其实会把实例化委托的时候, 给定的方法给指定掉;  执行委托还是执行方法;

        //5. 委托是一个类----得到类的实例, 就可以把实例当做参数来传递; 委托中可以可以执向某个方法, 如果把委托传递到特定的地方, 执行委托---可以把带过去的方法给执行掉;
        //6. 委托的作用: 可以把方法(行为)当做参数来传递;  
        //7. 实例化 , 注意: 一定要执向的方法必须和委托的参数和返回值完全吻合;

        public void Show()
        {
            NoReturnNoPara method01 = new NoReturnNoPara(this.DoNothing);
            method01.Invoke(); //执行委托 
            NoReturnWithPara mehthod1 = new NoReturnWithPara(this.NoReturnWithParaMehtod);
            mehthod1.Invoke(13, 134);

            NoReturnNoPara method03 = this.DoNothing;
            NoReturnNoPara method04 = () => { };  //委托的实例, 可以直接指向一个方法, 或者是一个lamada表达式 
        }

        private void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }

        private void DoObject(object? state)
        {
            Console.WriteLine("This is DoNothing");
        }

        private void DoNothing(int i)
        {
            Console.WriteLine("This is DoNothing");
        }

        private void NoReturnWithParaMehtod(int x, int y)
        {
            Console.WriteLine($"这是一个带参数无返回值的方法。。。");
        }

        private int WithReturnNoParaMehtod()
        {
            Console.WriteLine($"这是一个无参数带返回值的方法。。。");
            return default;
        }

        private int WithReturnWithParaMehtod(out int x, ref int y)
        {
            Console.WriteLine($"这是一个带参数无返回值的方法。。。");
            x = 1;
            return default;
        }

    }

    public class OtherClass
    {
        public void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }
        public static void DoNothingStatic()
        {
            Console.WriteLine("This is DoNothingStatic");
        }
    }

}
